<?


/*

+--------------------------------------------------------------------------

|   wjl 文件上传类 ＋ 1.0

|   ========================================

|   taft@team. wjl

|   http://wjl.cn

|   +----------------------------------------------------------------------

|

|   > 文件上传

|   > 完成日期：2005-3-5

|   > 已在原创版使用

|

|   +----------------------------------------------------------------------

|

|   quick reference

|   1. we should only invoke the public funcions.

|   2. methods user only needs concern are following(as the invoking step):

|      upload_file[constuctor]

|      set_file_name_size( $_FILE[your_form_var][name],$_FILE[your_form_var][size] )

|      set_upfile( $_FILE[your_form_var][tmp_file] )

|      do_save()

|   3. don't mess up the code alone before you report any grateful bug to me.

+--------------------------------------------------------------------------

*/

class upload_file {

	/**声明**/
	var $upfile_size, $upfile_name, $upfile, $filename, $type;
	var $up_extention;
	var $prefix, $bad_extention_list, $file_path, $base_directory;
	var $limit_size = 1024;
	var $file;
	var $saveType = 1; //保存类型 如果为1 则只保存裁剪后的图片 如果为10则保存原始的图片 如果为100则都保存
	var $extension_whitelist = array("jpg", "gif", "png");	// Allowed file extensions
	/**
	 *     构造函数
	 *     @param  $prefix          string 文件名前缀，比如时间，避免上传文件重名
	 *     @param  $bad_extention   string 不允许上传文件扩展名
	 *     @param  $base_directory  string 文件保存目录
		*     @param  $size            int    文件大小 
		*     @param  string $file
	 *     @return 
	 *
	 *     @access public
	 */
    function getFileType()
    {
    	return $this->up_extention;
    }
	function upload_file($prefix, $base_directory, $size, $file, $saveType = 100) {
		$this->bad_extention_list = "php,exe,rar,txt,"; //初始化扩展名列表;
		if ($size != 0) {
			$this->limit_size = $size; //初始化上传文件KB限制;
		}
		$this->prefix = $prefix.time().rand(0,100000); //设置文件名称前缀;
		//$this->base_directory=$base_directory.date("Ymd")."/";  //初始化文件上传根目录名，可修改！;
		$this->base_directory = $base_directory.date("Ym")."/"; //初始化文件上传根目录名，可修改！;        
		$this->file = $_FILES[$file];
		$path_info = pathinfo($this->file['name']);
	    $this->type = $path_info["extension"];
		$this->upfile_name = $this->file['name']; //取得文件名称;
		$this->filename = $this->prefix;
		$this->upfile_size = $this->file['size']; //取得文件尺寸;		
		$this->saveType = $saveType;
		$this->upfile = $this->file['tmp_name'];
	}

	/**
	 *     得到$_FILE信息
		*     @param  $upfile_name     string $_FILE[][name]
		*     @param  $upfile_size     string $_FILE[][size]
	 *     @return 
	 *
	 *     @access public
	 */

	function set_file_name_size($upfile_name, $upfile_size) {

		$this->upfile_name = $upfile_name; //取得文件名称;
		$this->filename = $this->prefix;
		$this->upfile_size = $upfile_size; //取得文件尺寸;
	}
	/**
	 *     取得文件在服务端储存的临时文件名
	 *     @param  $upfile    string $_FILE[][tmp_name]
	 *     @return 
	 *
	 *     @access public
	 */

	function set_upfile($upfile) {
		$this->upfile = $upfile;
	}

	/**
	 *     检测扩展名是否违规
	 *     @return 
	 *
	 *     @access private
	 */

	function _check() {
		$check = false;
		if($this->upfile_name==null)
		{
			return "errorNull";
		}
		$this->up_extention = strtolower(preg_replace('/.*\.(.*[^\.].*)*/iU', '\\1', $this->upfile_name)); //取得文件扩展名;
		$ext = explode("|", $this->bad_extention_list); //以"|"来分解默认扩展名;
		for ($i = 0; each($ext); $i++) //遍历数组;
			{
			if ($ext[$i] == $this->up_extention) //比较文件扩展名是否与默认允许的扩展名相符;
				{
				$check = false; //相符则标记;
				break;
			}
		}
		//  echo $this -> type;
		//var_dump($this->extension_whitelist);
		foreach ($this->extension_whitelist as $extension) 
		{
			if (strcasecmp($this->type, $extension) == 0) 
			{
				//file_put_contents("aaa.txt","eeeeeeeeeeeeeeeeeeeeeeeeee".$this->type,FILE_APPEND);
				$check = true;
				break;
			}
		}
		
		if (!$check) 
		{
			//$this->showmsg($ADMIN->lang['wrong_type'] . $this->up_extention);
			return "errorType";
		}

		/**检测文件大小是否超标**/

		if ($this->upfile_size > round($this->limit_size * 1024)) //文件的大小是否超过了默认的尺寸;
		{
		    return "errorSize";		
		} //超过则警告;
        return "true";
	}
	function createDir($path) 
	{
        #     echo $path,'<BR>' ;        #看看创建过程，反的哦
        $path = str_replace('\\\\','/',$path) ;
        if ( is_dir($path) )
        {
        	return true ;
        }
        if ( file_exists($path) )
        {
        	 return false ;    #   有文件挡路哦
        }
        $parent = substr($path ,0, strrpos($path,'/') ) ;
        if ( $parent==='' || $parent==='.' || $this->createDir( $parent ) )
        {
                 return @mkdir($path,7777) ;                #    没权限的话别怪我哦
        }
        else
        {
        	return false ;
        }
	}
	/**
	 *     拷贝文件到指定文件
	 *     @return  成功则文件的完整访问路径，失败返回0
	 *
	 *     @access private
	 */

	function _copy_file() {

		global $CONF;
		$this->base_directory = iconv("UTF-8", "GB2312", $this->base_directory);
		$this->createDir($this->base_directory);
		//生成文件完整访问路径;   
		$this->file_path = $this->base_directory . $this->filename . "o." . $this->up_extention;
		//echo $this->file_path;
		if (copy($this->upfile, $this->file_path)) 
		{
			if($this->saveType==100)
			{
				$small = $this->base_directory . $this->filename . "r." . $this->up_extention;
				$this->_resize($small, $this->file_path, "php", "");
			}
//			/$this->resizeImage($this->file_path,$small,100,100);
			return iconv("GB2312", "UTF-8", $this->file_path); //上传文件;
		} 
		else
		{
			return 0;
		}

		//print $this->showerror("意外错误，请重试！");     //上传失败;

	}
	/**
	 *     完成文件上传
	 *     @return  成功则文件的完整访问路径，失败返回0
	 *
	 *     @access public
	 */

	function do_save() 
	{
	    $status = $this->_check(); 
		if($status=="true")
		{
			return $this->_copy_file(); //上传文件;
		} //检测文件扩展名是否违规,大小是否超限;
		else
		{
			return $status;
		}
	}
	//指定上传文件的路径及名称
	function do_save_sign_name($filename) 
	{
	    $status = $this->_check(); 
		if($status=="true")
		{
			$this->file_path = $filename;
            $folders = split("/",$filename);
            $this->base_directory =null;
            $i = 1;
            foreach($folders as $value)
            {
            	if($i<count($folders))
            	{
            		$this->base_directory = $this->base_directory ."/".$value;
            	}
            	$i++;
            }
            $this->base_directory = substr($this->base_directory,1);
			$this->base_directory = iconv("UTF-8", "GB2312", $this->base_directory);
			$this->createDir($this->base_directory);
			$this->file_path = iconv("UTF-8", "GB2312", $this->file_path);
			if (copy($this->upfile, $this->file_path)) 
			{
				return iconv("GB2312", "UTF-8", $this->file_path); //上传文件;
			}
			else
			{
				return 0;
			}
		} //检测文件扩展名是否违规,大小是否超限;
		else
		{
			return $status;
		}
	}
	/** the rest is for debuging **/

	function showerror($errstr = "Undefined error!") {
		echo "<script language=javascript>alert('$errstr');location='javascript:history.go(-1);';</script>";
		exit ();
	}
	function showmsg($msgstr) {
		echo "<script language=javascript>alert('$msgstr');</script>";
	}
	function echo_file_path() {
		return $this->file_path;
	}

	//----------------- Add by 縮圖外掛 --------------------------- 
	function _resize($dest, $src, $imglib, $convert_path) {

		$quality = 82; //----JPG 

		$image_info = getimagesize($src);
		$srcSize_W = $image_info[0];
		$srcSize_H = $image_info[1];

		$img_aspect = $srcSize_W / $srcSize_H;

		if ($srcSize_H > $srcSize_W * 2) 
		{
			define(SMALL_IMAGE_HEIGHT, 69);
		}
		if (SMALL_IMAGE_WIDTH > 0) 
		{
			$destSize_W = SMALL_IMAGE_WIDTH;
			$destSize_H = intval($destSize_W / $img_aspect);
		}
		else
		{
			if (SMALL_IMAGE_HEIGHT > 0) 
			{
				$destSize_H = SMALL_IMAGE_HEIGHT;
				$destSize_W = intval($destSize_H * $img_aspect);
			} 
			else 
			{
				$destSize_W = 79;
				$destSize_H = intval($destSize_W / $img_aspect);
			}
		}
		if ($imglib == "php") {
			//----------- With buildin php GD function -----------------------           

			$destImage = function_exists('imageCreateTrueColor') ? imageCreateTrueColor($destSize_W, $destSize_H) : imageCreate($destSize_W, $destSize_H);

			//imageAntiAlias($destImage,true); 
			//------消鋸齒演算，因看不出效果，故移除以節省時間。 

			switch ($image_info[2]) {
				case 1 : //GIF 
					$srcImage = imageCreateFromGif($src);
					imageCopyResampled($destImage, $srcImage, 0, 0, 0, 0, $destSize_W, $destSize_H, $srcSize_W, $srcSize_H);
					imagegif($destImage, $dest);
					//@copy ($src,$dest); 
					break;

				case 2 : //JPEG 
					$srcImage = imageCreateFromJpeg($src);
					//------- 進行縮圖演算--------------- 
					imageCopyResampled($destImage, $srcImage, 0, 0, 0, 0, $destSize_W, $destSize_H, $srcSize_W, $srcSize_H);
					imageJpeg($destImage, $dest, $quality);
					break;

				case 3 : //PNG 
					$srcImage = imageCreateFromPng($src);
					//------- 進行縮圖演算--------------- 
					imageCopyResampled($destImage, $srcImage, 0, 0, 0, 0, $destSize_W, $destSize_H, $srcSize_W, $srcSize_H);
					imagePng($destImage, $dest);
					break;

				default :
					return false;
					break;
			}
			if ($srcImage)
				imagedestroy($srcImage);
			if ($destImage)
				imagedestroy($destImage);

		} else {
			@ copy($src, $dest);
		}

	}

	//----------------- End of 縮圖外掛 --------------------------- 

	/*
	*说明：函数功能是把一个图像裁剪为任意大小的图像，图像不变形
	* 参数说明：输入 需要处理图片的 文件名，生成新图片的保存文件名，生成新图片的宽，生成新图片的高
	* written by smallchicken
	* time 2008-12-18
	*/
	// 获得任意大小图像，不足地方拉伸，不产生变形，不留下空白
	function resizeImage($src_file, $dst_file, $new_width, $new_height) {
		if ($new_width < 1 || $new_height < 1) {
			echo "params width or height error !";
			exit ();
		}
		if (!file_exists($src_file)) {
			echo $src_file . " is not exists !";
			exit ();
		}
		// 图像类型
		$type = exif_imagetype($src_file);
		$support_type = array (
			IMAGETYPE_JPEG,
			IMAGETYPE_PNG,
			IMAGETYPE_GIF
		);
		if (!in_array($type, $support_type, true)) {
			echo "this type of image does not support! only support jpg , gif or png";
			exit ();
		}
		//Load image
		switch ($type) {
			case IMAGETYPE_JPEG :
				$src_img = imagecreatefromjpeg($src_file);
				break;
			case IMAGETYPE_PNG :
				$src_img = imagecreatefrompng($src_file);
				break;
			case IMAGETYPE_GIF :
				$src_img = imagecreatefromgif($src_file);
				break;
			default :
				echo "Load image error!";
				exit ();
		}
		$w = imagesx($src_img);
		$h = imagesy($src_img);
		$ratio_w = 1.0 * $new_width / $w;
		$ratio_h = 1.0 * $new_height / $h;
		$ratio = 1.0;
		// 生成的图像的高宽比原来的都小，或都大 ，原则是 取大比例放大，取大比例缩小（缩小的比例就比较小了）
		if (($ratio_w < 1 && $ratio_h < 1) || ($ratio_w > 1 && $ratio_h > 1)) {
			if ($ratio_w < $ratio_h) {
				$ratio = $ratio_h; // 情况一，宽度的比例比高度方向的小，按照高度的比例标准来裁剪或放大
			} else {
				$ratio = $ratio_w;
			}
			// 定义一个中间的临时图像，该图像的宽高比 正好满足目标要求
			$inter_w = (int) ($new_width / $ratio);
			$inter_h = (int) ($new_height / $ratio);
			$inter_img = imagecreatetruecolor($inter_w, $inter_h);
			imagecopy($inter_img, $src_img, 0, 0, 0, 0, $inter_w, $inter_h);
			// 生成一个以最大边长度为大小的是目标图像$ratio比例的临时图像
			// 定义一个新的图像
			$new_img = imagecreatetruecolor($new_width, $new_height);
			imagecopyresampled($new_img, $inter_img, 0, 0, 0, 0, $new_width, $new_height, $inter_w, $inter_h);
			switch ($type) {
				case IMAGETYPE_JPEG :
					imagejpeg($new_img, $dst_file, 100); // 存储图像
					break;
				case IMAGETYPE_PNG :
					imagepng($new_img, $dst_file, 100);
					break;
				case IMAGETYPE_GIF :
					imagegif($new_img, $dst_file, 100);
					break;
				default :
					break;
			}
		} // end if 1
		// 2 目标图像 的一个边大于原图，一个边小于原图 ，先放大平普图像，然后裁剪
		// =if( ($ratio_w < 1 && $ratio_h > 1) || ($ratio_w >1 && $ratio_h <1) )
		else {
			$ratio = $ratio_h > $ratio_w ? $ratio_h : $ratio_w; //取比例大的那个值
			// 定义一个中间的大图像，该图像的高或宽和目标图像相等，然后对原图放大
			$inter_w = (int) ($w * $ratio);
			$inter_h = (int) ($h * $ratio);
			$inter_img = imagecreatetruecolor($inter_w, $inter_h);
			//将原图缩放比例后裁剪
			imagecopyresampled($inter_img, $src_img, 0, 0, 0, 0, $inter_w, $inter_h, $w, $h);
			// 定义一个新的图像
			$new_img = imagecreatetruecolor($new_width, $new_height);
			imagecopy($new_img, $inter_img, 0, 0, 0, 0, $new_width, $new_height);
			switch ($type) {
				case IMAGETYPE_JPEG :
					imagejpeg($new_img, $dst_file, 100); // 存储图像
					break;
				case IMAGETYPE_PNG :
					imagepng($new_img, $dst_file, 100);
					break;
				case IMAGETYPE_GIF :
					imagegif($new_img, $dst_file, 100);
					break;
				default :
					break;
			}
		} // if3
	} // end function

}
?>